/***************************************************
 *  ____              ___   ____                   *
 * |  _ \ __ _ _ __  ( _ ) / ___|  ___ __ _ _ __   *
 * | |_) / _` | '_ \ / _ \/\___ \ / __/ _` | '_ \  *
 * |  __/ (_| | | | | (_>  <___) | (_| (_| | | | | *
 * |_|   \__,_|_| |_|\___/\/____/ \___\__,_|_| |_| *
 *                                                 *
 ***************************************************/

#import "CoreText/CoreText.h"

#import "TRSDialView.h"

const NSInteger kTRSDialViewDefautLabelFontSize = 12;

const CGFloat kTRSDialViewDefaultMinorTickDistance = 18.0f;
const CGFloat kTRSDialViewDefaultMinorTickLength   = 5.0f;
const CGFloat KTRSDialViewDefaultMinorTickWidth    = 0.5f;

const NSInteger kTRSDialViewDefaultMajorTickDivisions = 5;
const CGFloat kTRSDialViewDefaultMajorTickLength      = 8.0f;
const CGFloat kTRSDialViewDefaultMajorTickWidth       = 1.0f;

@interface TRSDialView ()

@end

@implementation TRSDialView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _minimum = 0;
        _maximum = 0;

        _minorTicksPerMajorTick = kTRSDialViewDefaultMajorTickDivisions;
        _minorTickDistance = kTRSDialViewDefaultMinorTickDistance;

        self.backgroundColor = [UIColor clearColor];

        _labelStrokeColor = [UIColor colorWithWhite:1.0f alpha:0.6];
        _labelFillColor = [UIColor colorWithWhite:1.0f alpha:0.6];
        _labelStrokeWidth = 1.0;

        _labelFont = [UIFont systemFontOfSize:kTRSDialViewDefautLabelFontSize];

        _minorTickColor = [UIColor colorWithWhite:1.0f alpha:0.4];
        _minorTickLength = kTRSDialViewDefaultMinorTickLength;
        _minorTickWidth = KTRSDialViewDefaultMinorTickWidth;

        _majorTickColor = [UIColor colorWithWhite:1.0f alpha:0.6];
        _majorTickLength = kTRSDialViewDefaultMajorTickLength;
        _majorTickWidth = kTRSDialViewDefaultMajorTickWidth;
    }

    return self;
}

- (void)setDialRangeFrom:(NSInteger)from to:(NSInteger)to {

    _minimum = from;
    _maximum = to;
    
    // Resize the frame of the view
    CGRect frame = self.frame;
    
    frame.size.width = (_maximum - _minimum) * _minorTickDistance + _majorTickWidth + 2 * _leadingSpace;
    frame.size.width = MAX(frame.size.width, [UIScreen mainScreen].bounds.size.width);
    
    self.frame = frame;
    [self setNeedsDisplay];
}

- (void)setLeadingSpace:(NSInteger)leadingSpace
{
    _leadingSpace = leadingSpace;
    
    // Resize the frame of the view
    CGRect frame = self.frame;
    
    frame.size.width = (_maximum - _minimum) * _minorTickDistance + _majorTickWidth + 2 * _leadingSpace;
    frame.size.width = MAX(frame.size.width, [UIScreen mainScreen].bounds.size.width);
    
    self.frame = frame;
    [self setNeedsDisplay];
}

#pragma mark - Drawing

- (void)drawLabelWithContext:(CGContextRef)context
                     atPoint:(CGPoint)point
                        text:(NSString *)text
                   fillColor:(UIColor *)fillColor
                 strokeColor:(UIColor *)strokeColor {

    CGSize boundingBox;
    if ([text respondsToSelector:@selector(sizeWithAttributes:)]) {
        boundingBox = [text sizeWithAttributes:@{NSFontAttributeName:self.labelFont}];
    } else {
        boundingBox = [text sizeWithFont:self.labelFont];
    }

    CGFloat label_y_offset = -boundingBox.height - 2.0f;

    // We want the label to be centered on the specified x value
    NSInteger label_x = point.x - (boundingBox.width / 2);

    CGContextSetStrokeColorWithColor(context, strokeColor.CGColor);
    CGContextSetFillColorWithColor(context, fillColor.CGColor);

    CGContextSetLineWidth(context, self.labelStrokeWidth);
    
    // Set the drawing mode based on the presence of the file and stroke colors
    CGTextDrawingMode mode = kCGTextFillStroke;
    
    if ((fillColor == nil) && (strokeColor == nil))
        mode = kCGTextInvisible;
        
    else if (fillColor == nil)
        mode = kCGTextStroke;
    
    else if (strokeColor == nil)
        mode = kCGTextFill;
    
    CGContextSetTextDrawingMode(context, mode);

    // The center position
    CGRect textRect = CGRectMake(label_x, point.y + label_y_offset, boundingBox.width, boundingBox.height);

//    NSMutableParagraphStyle *style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
//    [style setLineBreakMode:NSLineBreakByTruncatingTail];
//    [style setAlignment:NSTextAlignmentCenter];

    NSDictionary *attributes = @{
                                 NSStrokeWidthAttributeName : @(-self.labelStrokeWidth),
                                 NSFontAttributeName : self.labelFont,
                                 NSForegroundColorAttributeName : fillColor,
                                 NSStrokeColorAttributeName : strokeColor
                                 };

    if ([text respondsToSelector:@selector(sizeWithAttributes:)]) {
        [text drawInRect:textRect withAttributes:attributes];
    } else {
        [text drawInRect:textRect withFont:self.labelFont];
    }
}

- (void)drawMinorTickWithContext:(CGContextRef)context
                         atPoint:(CGPoint)point
                       withColor:(UIColor *)color
                           width:(CGFloat)width
                          length:(CGFloat)length {

    CGContextSetStrokeColorWithColor(context, color.CGColor);
    CGContextSetLineWidth(context, width);

    CGContextMoveToPoint(context, point.x, point.y);
    CGContextAddLineToPoint(context, point.x, point.y + length);

    CGContextStrokePath(context);
}

- (void)drawMajorTickWithContext:(CGContextRef)context
                         atPoint:(CGPoint)point
                       withColor:(UIColor *)color
                           width:(CGFloat)width
                          length:(CGFloat)length {

    // Draw the line
    CGContextSetStrokeColorWithColor(context, color.CGColor);
    CGContextSetLineWidth(context, width);
//    CGContextSetLineCap(context, kCGLineCapRound);

    CGContextMoveToPoint(context, point.x, point.y);
    CGContextAddLineToPoint(context, point.x, point.y + length);

    CGContextStrokePath(context);
}

- (void)drawTicksWithContext:(CGContextRef)context atX:(long)x
{

    CGPoint point = CGPointMake(x, 0);

    if ([self isMajorTick:x]) {
        point = CGPointMake(x, self.bounds.size.height - self.majorTickLength);
        
        [self drawMajorTickWithContext:context
                               atPoint:point
                             withColor:self.majorTickColor
                                 width:self.majorTickWidth
                                length:self.majorTickLength];

        // Draw the text
        //
        // 1) Take the existing position and subtract off the lead spacing
        // 2) Divide by the minor ticks to get the major number
        // 3) Add the minimum to get the current value
        //
        NSString *text;

        int value = (point.x - self.leadingSpace) / self.minorTickDistance + _minimum;
        value *= 2;
        
        int min = value / 60;
        int sec = (value % 60);

        if (min == 0) {
            text = [NSString stringWithFormat:@":%02d", sec];
        } else {
            text = [NSString stringWithFormat:@"%d:%02d", min, sec];
        }

        [self drawLabelWithContext:context
                           atPoint:point
                              text:text
                         fillColor:self.labelFillColor
                       strokeColor:self.labelStrokeColor];

    } else {

        // Save the current context so we revert some of the changes laster
        CGContextSaveGState(context);
        point = CGPointMake(x, self.bounds.size.height - self.minorTickLength);

        [self drawMinorTickWithContext:context
                               atPoint:point
                             withColor:self.minorTickColor
                                 width:self.minorTickWidth
                                length:self.minorTickLength];

        // Restore the context
        CGContextRestoreGState(context);
    }
}

/**
 * Perform Custom drawing
 */
- (void)drawRect:(CGRect)rect
{
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Fill the background
    CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);

    CGContextFillRect(context, rect);
    
    // Add the tick Marks
    for (long i = self.leadingSpace; i < rect.size.width; i += self.minorTickDistance) {

        // After
        if (i > (self.frame.size.width - self.leadingSpace))
            break;

        // Middle
        else
            [self drawTicksWithContext:context atX:i];

    }
}

/**
 * Method to check if there is a major tick and the specified point offset
 * @param x [in] the pixel offset
 */
- (BOOL)isMajorTick:(long)x {

    long tick_number = (x - self.leadingSpace) / self.minorTickDistance;

    return (tick_number % self.minorTicksPerMajorTick) == 0;
}

@end

